home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 16 / AMIGAplus Sonderheft 16 (1998)(ICP)(DE)[!].iso / pd / spiele / zebulon / src / items.t < prev    next >
Text File  |  1997-01-14  |  28KB  |  899 lines

  1. /* $Id: items.t 1.16 96/04/16 21:56:36 mol Exp $
  2.  **********************************************************************
  3.  *
  4.  * Uncle Zebulon's Will, version 2.0
  5.  *
  6.  * An adventure game, written in TADS 2.2.
  7.  *
  8.  * items.t - Sundry items
  9.  *
  10.  **********************************************************************
  11.  * 
  12.  * Copyright (c) 1995-96 by Magnus Olsson (mol@df.lth.se).
  13.  * All rights reserved.
  14.  *
  15.  * This source code may be copied and distributed freely as long as the 
  16.  * following conditions are met:
  17.  *   - no fee may be charged for the code (a nominal fee may be charged
  18.  *     to cover distribution costs)
  19.  *   - the code is not modified in any way
  20.  *   - this copyright notice is not removed or modified in any way
  21.  *
  22.  * You may use individual parts of this code in your programs
  23.  * as long as they are attributed to the author. You are not allowed
  24.  * to use the plot, story, characters or text of the game without the
  25.  * written permission of the author.
  26.  *
  27.  ***********************************************************************/
  28.  
  29. /* 
  30.  * The letter you get from the demon.
  31.  */
  32. letter : readable
  33.     noun = 'letter'
  34.     sdesc = "letter"
  35.     ldesc = "I suggest you read it."
  36.  
  37.     readdesc = "The letter is written in uncle Zebulon's familiar hand.
  38.     \n\t\"My dear Richard,\n
  39.     When you read this, I'm afraid I'll have left this world for good.
  40.     By now you should have heard of my will and of the little 
  41.     jokes I have played on your relatives. I am sure they are all furious;
  42.     they had hoped for far more. Perhaps you too are angry with me, 
  43.     perhaps you think I should have been more generous towards you?\n
  44.     \tWell, let me tell you this: you've always been my favourite
  45.     nephew, because we share (I hope) the same basic outlook on life:
  46.     it's all a rather cruel game, with rules that are there to be 
  47.     circumvented. Playing fair doesn't mean you shouldn't do the unexpected!
  48.     I don't want to openly favour you before your cousins, but I think
  49.     you're far more likely than they are to exploit the advantages
  50.     of the situation. You may call it a little test, or game, or
  51.     whatever. My final advice to you is: follow the rules 
  52.     by the letter and you may find that new possibilities open up.
  53.     \b\t\t\t\tYour affectionate uncle, Zeb.\"\b"
  54.  
  55.     verDoOpen(actor) = {
  56.         "It's already open. Just go ahead and read it! ";
  57.     }
  58.     verDoThrow(actor) = {
  59.         "Throwing << self.adesc >> would be a futile exercise - 
  60.     the air resistance is far too high. ";
  61.     }
  62.     verDoThrowAt(actor, io) = {
  63.         self.verDoThrow(actor);
  64.     }
  65.  
  66.  
  67.     isread = nil
  68.     doRead(actor) = {
  69.      inherited.doRead(actor);
  70.     if (not isread) {
  71.         incscore(5);
  72.         isread := true;
  73.     }
  74.     }
  75.     
  76.     location = nil
  77. ;
  78.  
  79. /*
  80.  * The sheet of paper with Zebulon's poem.
  81.  */
  82. paper : readable, treasure
  83.     noun = 'paper' 'sheet' 'note' 'poem' 'text' 'writing'
  84.     adjective = 'writing'
  85.     sdesc = "sheet of writing paper"
  86.     ldesc = "On the paper, the following text is written in uncle
  87.         Zebulon's neat, regular hand:\b
  88.     
  89.     \tThe FIRST PORTAL deceives us all\n
  90.     \tBy making pairs of singles\n
  91.     \tA perfect match! Yet all illusion\n
  92.     \tA total likeness! And yet\n
  93.     \tAs different as left from right\n
  94.     \tForever kept apart by glass\n
  95.     \tUntil the touch of magic stars\n
  96.     \tTurns glass to air\n
  97.     \tAnd image to reality\n\b
  98.  
  99.      \tWhen the light of the Moon illuminates\n
  100.     \tThe Sun that never shines\n
  101.     \tThen open will the SECOND PORTAL\n
  102.     \tA dark, forbidding one, that scares\n
  103.     \tAnd rightly so! Yet victory\n
  104.     \tAwaits the one who enters it\n\b
  105.         
  106.         \tThe THIRD and FINAL PORTAL stands\n
  107.     \tIn a lone and dreary waste beyond the worlds\n
  108.     \tGateway to great adventures\n
  109.     \tGuarded by Gods of Time and War and Love\n
  110.     \tAn offering for each, and you may pass\n
  111.     \tEach gift should match one guardian.\n\b
  112.  
  113.         You can't help thinking that while Uncle Zebulon may have been 
  114.     a great storyteller, he was clearly an inferior poet. "
  115.     
  116.     doRead(actor) = { self.ldesc; }
  117.     verDoThrow(actor) = {
  118.         "Throwing << self.adesc >> would be a futile exercise - 
  119.     the air resistance is far too high. ";
  120.     }
  121.     verDoThrowAt(actor, io) = {
  122.         self.verDoThrow(actor);
  123.     }
  124. ;
  125.  
  126.     
  127.  
  128. /*
  129.  * "Interactive fiction" has a slightly different meaning in this
  130.  * world...
  131.  */
  132. book : readable, treasure
  133.     noun = 'book' 'fiction' 'dork' 'trilogy' 'story' 'tale' 'literature'
  134.     adjective = 'dork' 'interactive'
  135.     sdesc = "book"
  136.     read = nil
  137.     ldesc = {
  138.       "As you open the book and flip through the pages, you find
  139.         that it's a piece of interactive fiction: a magic, heavily
  140.     enchanted book where the entire story changes in response to
  141.     choices made by the reader.\n
  142.     \tThis particular one happens to be one of the great classics
  143.     of the genre: 'Dork', the story of a young man entering a great
  144.     underground computing centre, vanquishing the evil Hacker of
  145.     Foobar, and finally becoming System Manager. Of course, the 
  146.     story may sound a bit childish - everyone knows that computers
  147.     only exist in fairytales and that hackers are purely 
  148.     mythical creatures - but it's still immensely popular. ";
  149.  
  150.     if (not read) {
  151.         "\bAs you close the book again, a sheet of paper falls
  152.         out of it and flutters to the ground. ";
  153.         incscore(5);
  154.         paper.moveInto(Me.location);
  155.         setit(paper);
  156.         read := true;
  157.     }
  158.     }
  159.     
  160.     doRead(actor) = { self.ldesc; }
  161.     verDoLookin(actor) = { }
  162.     doLookin(actor) = { self.ldesc; }
  163.     verDoOpen(actor) = { }
  164.     doOpen(actor) = { self.ldesc; }
  165.     verDoClose(actor) = {
  166.         "It's already closed. ";
  167.     }
  168.     verDoFlipThru(actor) = { }
  169.     doFlipThru(actor) = { self.ldesc; }
  170.     
  171.     location = desk
  172. ;    
  173.  
  174.  
  175. scroll : readable, treasure
  176.     noun = 'scroll' 'paper' 'note' 'text' 'writing' 'piece' 'roll'
  177.     adjective = 'paper' 'thick' 'rolled-up'
  178.     sdesc = "scroll"
  179.     ldesc = "\^<< self.thedesc >> is a rolled-up piece of rather thick 
  180.          paper. To your amazement, you notice that there's something 
  181.     written on it, and in uncle Zebulon's handwriting (what a 
  182.     surprise!). "
  183.  
  184.     readdesc = "My dear nephew,\b\t
  185.         I'm glad that you've discovered the way through the mirror, and
  186.     into my secret tower. It's here, in the realm you can see from
  187.     the windows, that I've spent most of my time the last few years,
  188.     the time you and your relatives thought I was just pent up inside 
  189.     my house. I may not have collected much gold and belongings in your
  190.     world, but in the world of Vhyl and the city of Cyr-Dhool are
  191.     treasures beyond belief and adventures that surpass your wildest
  192.     dreams.\b\t
  193.     The portal to Vhyl is hidden, but I have no doubt that you will
  194.     find it. Once you've opened it, and passed the portal that's
  195.     beyond it, your true inheritance awaits you, at the end of a quest
  196.     I shall never have the time to finish. Your relatives have no
  197.     doubt already removed what little there is of value in my house;
  198.     what they have left behind, however, may be of more use to you.
  199.     \b\t\t\tWith hope of your success, 
  200.     \n\t\t\t\tyour affectionate uncle,\n
  201.     \t\t\t\t\t\tZebulon\n"
  202.  
  203.     location = tower
  204. ;
  205.  
  206. /*
  207.  * A flask of acid.
  208.  */
  209. flask : container, breakable, treasure
  210.     noun = 'flask' 'bottle' 'beaker' 
  211.     adjective = 'small' 'glass'
  212.     sdesc = "small glass flask"
  213.     ldesc = {
  214.         "This is a small glass flask, of the type often found in
  215.         alchemistry labs. ";
  216.     if (itemcnt(contents) > 0) {
  217.         "It contains ";
  218.           listcont(self);
  219.         ". ";
  220.     }
  221.     }
  222.     location = moor_gnittis
  223.     
  224.     // As long as there is acid in the bottle, we have isqcontainer = true
  225.     // so the acid doesn't get listed. After it has disappeared, we
  226.     // set isqcontainer to nil, since then the flask is like any other
  227.     // container.
  228.     isqcontainer = true 
  229.  
  230.     ioPutIn(actor, dobj) = {
  231.         if (dobj.bulk > 0) // Only small objects will fit inside
  232.         "That's too large to fit in << self.thedesc >>. ";
  233.     else if (acid.isIn(self))
  234.         // Let the acid take care of anything put into it.
  235.         acid.ioPutIn(actor, dobj);
  236.     else
  237.         pass ioPutIn;
  238.     }
  239. ;
  240.  
  241. acid : item
  242.     noun = 'liquid' 'acid' 'poison' 'quantity' 'fluid'
  243.     adjective = 'green' 'greenish' 'poisonous' 'acidic' 'liquid'
  244.     sdesc = "greenish liquid"
  245.     adesc = "a quantity of greenish liquid"
  246.     thedesc = "the greenish liquid"
  247.     ldesc = "The liquid is rather thick, faintly greenish, and has
  248.         a decidedly unpleasant smell. "
  249.  
  250.     islisted = nil
  251.     location = flask
  252.     used_on = nil // The latest object the acid was used on.
  253.         
  254.     verDoDrink(actor) = {
  255.         "\^<< self.thedesc >> looks decidedly noxious. It's probably
  256.     poisonous as well. ";
  257.     }
  258.  
  259.     verDoPourOn(actor, io) = {
  260.         if (io = flask)
  261.          "But << self.thedesc >> is already inside the flask! ";
  262.     else if (io = self)
  263.             "Don't be ridiculous! ";
  264.     else if (io = gold_ball or isclass(io, coin) or isclass(io, lens))
  265.         "It would probably be safer to 
  266.         put << io.thedesc >> in << self.thedesc >> instead. ";
  267.     else if (used_on <> nil) {
  268.         "Considering what happened ";
  269.         if (used_on = io)
  270.             "last time";
  271.         else
  272.             "when";
  273.         " you poured the liquid on << used_on.thedesc >>, you
  274.         decide not to try this experiment. ";
  275.     }
  276.     }
  277.         
  278.     doPourOn(actor, io) = {
  279.         used_on := io;
  280.     
  281.     "You carefully pour a single drop of << self.thedesc >>\
  282.     on << io.thedesc >>. With a hissing sound and a 
  283.     cloud of acrid, green smoke, the liquid burns a small hole
  284.     in its surface. This must obviously be some strong 
  285.     acid. Nasty stuff! ";
  286.     }
  287.  
  288.     doSynonym('PourOn') = 'PutOn'
  289.  
  290.     verIoPutIn(actor) = {
  291.         flask.verIoPutIn(actor);
  292.     }
  293.     ioPutIn(actor, dobj) = {
  294.         if (dobj.bulk > 0) // Only small objects will fit inside
  295.         "That's too large to fit in << flask.thedesc >>. ";
  296.     else {
  297.         used_on := dobj;
  298.         
  299.             "\^<< dobj.thedesc >> falls into << self.thedesc >>, which 
  300.            begins to foam and bubble with a hissing sound. Acrid green
  301.         fumes billow out of the flask, making your eyes water. ";
  302.  
  303.         if (dobj <> silver_coin and dobj <> gold_ball) {
  304.                "After a while, the reaction subsides, and the liquid stops
  305.             fuming. No trace remains of << dobj.thedesc >>. ";
  306.             dobj.moveInto(nil);
  307.         }
  308.         else {
  309.             flask.isqcontainer := nil;
  310.             "The reaction doesn't stop until all the liquid has boiled
  311.         away. ";
  312.         self.moveInto(nil);
  313.         if (dobj = silver_coin) {
  314.               "\^<< dobj.thedesc >> seems to have grown darker and 
  315.             duller. In fact, it doesn't look like silver at all 
  316.             any more, but more like iron. ";
  317.             silver_coin.moveInto(nil);
  318.             iron_coin.moveInto(flask);
  319.             setit(iron_coin);
  320.         }
  321.         else if (dobj = gold_ball) {
  322.               "\^<< dobj.thedesc >> has been affected in quite a
  323.             dramatic way by the reaction - it's not golden at
  324.             all, but a dull, greyish-white colour. In fact, it
  325.             looks like the gold has turned into zinc. ";
  326.             dobj.moveInto(nil);
  327.             zinc_ball.moveInto(flask);
  328.             setit(zinc_ball);
  329.         }        
  330.         }    
  331.     }
  332.     }
  333.     
  334.     // Don't let the player take the acid from the flask.
  335.     verifyRemove(actor) = {
  336.         if (used_on = nil)
  337.         "You've always been careful when handling unknown chemicals,
  338.         and you're not going to take any risks with this specimen.
  339.         Prudently, you decide to keep it in its flask. ";
  340.     else
  341.         "After seeing what happened to << used_on.thedesc >>, you
  342.         think it prudent to let << self.thedesc >> stay in 
  343.         its flask. ";
  344.     }
  345.     verDoPour(actor) = {
  346.         self.verifyRemove(actor);
  347.     }
  348.  
  349.     verDoTake(actor) = {
  350.     flask.verDoTake(actor);
  351.     }
  352.     doTake(actor) = {
  353.     flask.doTake(actor);
  354.     }
  355.  
  356.     verDoTakeOut(actor, io) = {
  357.         if (io <> nil and not self.isIn(io))
  358.             "\^<< self.thedesc >> isn't in << io.thedesc >>. ";
  359.     inherited.verDoTake(actor);   // ensure object can be taken at all 
  360.     }
  361. ;
  362.  
  363. /* 
  364.  * The vegetables are actually treasures. The demon must be quite literal-
  365.  * minded, mustn't he?
  366.  */    
  367. carrot : treasure, fooditem
  368.     noun = 'carrot' 'vegetable' 'food'
  369.     adjective = 'large' 'big' 'huge' 'dry'
  370.     sdesc = "large carrot"
  371.     ldesc = "It looks rather dry and doesn't seem very appetizing. "
  372.  
  373.     verDoEat(actor) = {
  374.         if (location <> actor) 
  375.         "But you're not holding << self.thedesc >>! ";
  376.     else
  377.         "\^<< self.thedesc >> looks rather dry and doesn't seem 
  378.         very appetizing. It doesn't smell very appetizing either.
  379.         Come to think of it, you're not very hungry. ";
  380.     }
  381.     
  382.     wand_effect = {
  383.         local loc = self.location;
  384.     
  385.         ". The stars collect in a cloud around the carrot, which starts
  386.     to undergo a curious transformation, growing smaller and
  387.     rounder and redder and... When the stars 
  388.     gradually fade away, you see that the carrot has turned
  389.     into a big, succulent tomato. Amazing - you must have found
  390.     a wand of Vegetable Polymorphism! ";
  391.  
  392.     self.moveInto(nil);
  393.     tomato.moveInto(loc);
  394.     }
  395.     location = kitchen
  396. ;    
  397.  
  398. tomato : treasure, fooditem
  399.     noun = 'tomato' 'fruit' 'vegetable' 'food'
  400.     adjective = 'large' 'red' 'juicy' 'succulent' 'big'
  401.     sdesc = "tomato"
  402.     ldesc = "\^ << self.thedesc >> is large, red and looks much more 
  403.         appetizing than the carrot did. "
  404.  
  405.     verDoEat(actor) = {
  406.         if (location <> actor) 
  407.         "But you're not holding << self.thedesc >>! ";
  408.     else
  409.         pass verDoEat;
  410.     }
  411.     doEat(actor) = {
  412.         "The tomato is just as delicious as it looks. As you take
  413.     the last bite out of it, you feel something hard between
  414.     your teeth. Surprised, you remove << copper_coin.adesc >> from
  415.     your mouth. How on earth did that get into the tomato? ";
  416.     
  417.     copper_coin.moveInto(actor);
  418.     self.moveInto(nil);
  419.     setit(copper_coin);
  420.     incscore(5);
  421.     }
  422.     
  423.     wand_effect = {
  424.         local loc = self.location;
  425.     
  426.         " that strike << self.thedesc >> and explode with little popping
  427.     noises. The tomato starts to elongate, its colour changing into
  428.     orange, and has sooned turned back into a carrot. Those wands of
  429.     Vegetable Polymorphism may be pretty useless, but they are great 
  430.     fun, aren't they? ";
  431.     self.moveInto(nil);
  432.     carrot.moveInto(loc);
  433.     }
  434. ;    
  435.  
  436. /*
  437.  * A crystal ball that makes you see things.
  438.  */    
  439. crystal_ball : treasure
  440.     noun = 'ball' 'crystal' 'orb' 'sphere'
  441.     adjective = 'crystal' 'spherical'
  442.     sdesc = "crystal ball"
  443.     ldesc = "It's about fifteen centimetres in diameter. Unlike ordinary 
  444.     crystal, it doesn't sparkle in the light;
  445.     instead, it seems to glow with a misty radiance. You feel an
  446.     almost irresistible urge to gaze into it, as if you were some
  447.     common fortune-teller. "
  448.     
  449.     verDoLookin(actor) = { }
  450.     doLookin(actor) = {
  451.         "The interior of the crystal ball is surprisingly cloudy, almost
  452.     as if you were looking into murky water. Soon, however, the mist
  453.     seems to clear, giving place to an image of << self.vision >> 
  454.     \n\tPresently, the vision fades away, and the crystal gets 
  455.     cloudy again. ";
  456.     }
  457.  
  458.     // The vision method prints a new vision the first five times you 
  459.     // look into the ball. Vision_count keeps track of which vision you see.
  460.     vision_count = 0   
  461.     vision = {
  462.         switch (++vision_count) {
  463.         case 1:
  464.             "uncle Zebulon putting coins into a bottle. ";
  465.         break;
  466.         case 2:    
  467.             "yourself searching through a large packing crate. ";
  468.         break;
  469.         case 3:
  470.             "a young girl throwing a coin into a well, making a
  471.         wish with her eyes closed. ";
  472.         break;
  473.         case 4: 
  474.             "uncle Zebulon aiming a wand at a large carrot. The
  475.         carrot turns into a very surprised-looking rabbit.
  476.         Uncle Zebulon chuckles. ";
  477.         break;
  478.         default:
  479.         "yourself looking into a crystal ball. ";
  480.         --vision_count; // To avoid overflow.
  481.     }
  482.     }
  483.     location = desk
  484. ;
  485.  
  486. /*
  487.  * The magic wand. Pointing it at something will cause the wand_effect
  488.  * method of that object to be run.
  489.  */
  490. wand : hiddenItem, treasure
  491.     noun = 'wand' 'rod'
  492.     adjective = 'magic' 'magical' 'wood' 'ebony' 'narrow' 'tapering'
  493.     sdesc = "magic wand"
  494.     ldesc = "This looks like a typical magic wand of the sort used
  495.         by every wizard around the country: a narrow, tapering rod,
  496.     about thirty centimetres long, and made of some dark 
  497.     wood, probably ebony. Your uncle used to have
  498.     several, and you've often seen him point them at things, with
  499.     various interesting results. "
  500.  
  501.     verDoWave(actor) = {
  502.         "Wands like this one are most effectively used by pointing
  503.     them at things, not waving them around at random. ";
  504.     }
  505.     verDoPointAt(actor, io) = {
  506.         if (not actor.isCarrying(self))
  507.         "But %you% %are%n't carrying << self.thedesc >>! ";
  508.     else if (io = self)
  509.         "Pointing << self.thedesc >> at itself is rather difficult. ";
  510.     }        
  511.     doPointAt(actor, io) = {
  512.         "The wand sputters, emitting a stream of brilliantly shining
  513.         stars"; 
  514.     // An example of object orientation in action: each object knows
  515.     // best itself what happens when you aim the wand at it.
  516.         io.wand_effect;
  517.     }
  518.   
  519.     searchLoc = armchair // hidden in the armchair
  520.     found = nil
  521. ;
  522.     
  523. /*
  524.  * Verbs for waving and pointing the wand at things.
  525.  */
  526. waveVerb : deepverb
  527.     verb = 'wave'
  528.     sdesc = "wave"
  529.     doAction = 'Wave'
  530. ;
  531.  
  532. pointVerb : deepverb
  533.     verb = 'point' 'aim'
  534.     sdesc = "point"
  535.     prepDefault = atPrep
  536.     ioAction(atPrep) = 'PointAt'
  537. ;
  538.  
  539. /*
  540.  * Add methods to thing so that objects can be waved and pointed,
  541.  * as well as a default message when you aim the wand at something.
  542.  */
  543. modify thing
  544.     verDoWave(actor) = {
  545.         if (actor.isCarrying(self))
  546.             "Waving << self.thedesc >> about would be absolutely pointless,
  547.             at least in this game. ";
  548.     else
  549.         "But %you% %are%n't carrying << self.thedesc >>! ";
  550.     }
  551.     verDoPointAt(actor, io) = {
  552.         if (not actor.isCarrying(self))
  553.         "But %you% %are%n't carrying << self.thedesc >>! ";
  554.     else if (io = self)
  555.         "Pointing << self.thedesc >> at itself is rather difficult. ";
  556.     else if (isclass(io, movableActor))
  557.             "Pointing things at people isn't polite! ";
  558.     else    
  559.             "Nothing happens. ";
  560.     }        
  561.     verIoPointAt(actor) = { }
  562.     ioPointAt(actor, dobj) = {
  563.         dobj.doPointAt(actor, self);
  564.     }
  565.     wand_effect = {
  566.         " that strike << self.thedesc >> and explode with little popping
  567.     noises, seemingly without affecting it. Quite impressive fireworks,
  568.     but you can't really see the point of it all. Perhaps this is why
  569.     this wand was left lying around? ";
  570.     }
  571. ;
  572.  
  573. /*
  574.  * Aiming the wand at distant items is of course allowed, but not
  575.  * very useful.
  576.  */
  577. modify distantItem
  578.     iobjGen(a, v, d, p) = { 
  579.         if ((v <> pointVerb and v <> throwVerb) or p <> atPrep)
  580.          self.dobjGen(a, v, d, p); 
  581.     }
  582.     wand_effect = {
  583.         " in the general direction of << self.thedesc >>. Halfway through
  584.     the air, they explode with little popping noises. Quite impressive 
  585.     fireworks, but is it really useful? ";
  586.     }
  587.  
  588. ;
  589.  
  590. /*
  591.  * Coins - there are several with identical behaviour, 
  592.  * so we make a special class for them.
  593.  */
  594. class coin : treasure
  595.     ldesc = {
  596.        if (location = basin)
  597.         self.basin_ldesc;
  598.     else
  599.         self.ordinary_ldesc;
  600.     }
  601.  
  602.     ordinary_ldesc = {
  603.         pass ldesc; 
  604.     }
  605.     basin_ldesc = "It's resting on the bottom of << basin.thedesc >>. "
  606.  
  607.     // We can't reach coins that are in the basin. Note that this method
  608.     // is only needed for the coin class, since the basin doesn't accept
  609.     // any other objects than coins.            
  610.     dobjGen(a, v, i, p) = {
  611.         if (location = basin and v <> inspectVerb and v <> takeVerb) {
  612.             "You can't reach it from here. ";
  613.             exit;
  614.         }
  615.     else
  616.         pass dobjGen;
  617.     }
  618. ;
  619.  
  620. lead_coin : coin
  621.     noun = 'coin' 'money' 
  622.     adjective = 'lead' 'frobnizzian' 'frob' 'quarter-frob' 'grey' 'gray'
  623.            'octagonal'
  624.     plural = 'coins'
  625.     sdesc = "lead coin"
  626.     ordinary_ldesc = "Lead may not the most practical of 
  627.         materials for coinmaking, but this coin is actually made of 
  628.     grey, soft lead. Not only the metal, but also the shape, 
  629.     of the coin is unusual: it's octagonal.    It bears the image 
  630.     of a trident, surrounded by curious letters you can't read.\n\t
  631.     (In fact, this coin happens to be a genuine
  632.     quarter-frob piece from the country of Frobnizzia. The Frobnizzian
  633.     coins are notable for the great variety of materials used in making
  634.     them; especially notable is the one-gnark coin (one gnark being
  635.     equal to 27 2/3 frobs), which was a granite disk two feet in 
  636.     diameter. The size and weight of this coin were intended to 
  637.     deter purse-snatchers; unfortunately, they had other effects as
  638.     well, such as being the major cause of the collapse of the 
  639.     Frobnizzian economy.) "
  640.     
  641.     bulk = 0
  642.     location = hall
  643. ;
  644.  
  645. copper_coin : coin
  646.     noun = 'coin' 'money'
  647.     plural = 'coins' 
  648.     adjective = 'round' 'copper' 'frobnizzian' 'frob'
  649.     sdesc = "copper coin"
  650.     ordinary_ldesc = "Even though it's from Frobnizzia, a country that's 
  651.         renowned for its curious currency, there's nothing remarkable
  652.     whatsoever about this coin (in fact, it's remarkable for being
  653.     the only non-remarkable Frobnizzian coin). It's small, round,
  654.      made of copper, and bears the picture of a heart. "
  655.     bulk = 0
  656. ;    
  657.  
  658. iron_coin : coin
  659.     noun = 'coin' 'money'
  660.     adjective = 'iron' 'hexagonal' 'two-frob' 'frob' 'frobnizzian'
  661.     plural = 'coins' 
  662.     sdesc = "iron coin"
  663.     adesc = "an iron coin"
  664.     
  665.     ordinary_ldesc = "This coin, a Frobnizzian two-frob piece, is 
  666.     hexagonal and made of iron. It bears the picture of a sword. "
  667.     bulk = 0
  668. ;
  669.  
  670. silver_coin : coin
  671.     noun = 'coin' 'money'
  672.     adjective = 'silver' 'hexagonal' 'nineteen-frob' 'frob' 'frobnizzian'
  673.     plural = 'coins' 
  674.     sdesc = "silver coin"
  675.     ordinary_ldesc = "This coin, a Frobnizzian nineteen-frob piece, is 
  676.     hexagonal and made of silver. It bears the picture of a crescent. "
  677.     bulk = 0
  678.     location = receive_bottle
  679. ;
  680.  
  681. /*
  682.  * Some containers to hide the last lens.
  683.  */
  684. teak_box : openable, treasure, hiddenItem
  685.     noun = 'box' 'container'
  686.     adjective = 'small' 'teak' 'polished' 'wood' 'wooden' 
  687.     sdesc = "small teak box"
  688.     ldesc = {
  689.         "This small box is made of exquisitely crafted teak wood,
  690.         with a highly polished surface. 
  691.     It is << isopen ? "open" : "closed" >>. ";
  692.     if (isopen and itemcnt(contents) > 0) {
  693.         "Inside it, %you% see%s% "; 
  694.         listcont(self);
  695.         ". ";
  696.     }
  697.     }
  698.     isopen = nil
  699.     maxbulk = 0
  700.     searchLoc = wood_shavings
  701. ;
  702.  
  703. packing_crate : openable, treasure
  704.     noun = 'crate' 'box' 
  705.     adjective = 'packing' 'wood' 'wooden'
  706.     sdesc = "packing crate"
  707.     
  708.     verifyRemove(actor) = {
  709.         "It's far too heavy and bulky for a single person to 
  710.     carry around. ";
  711.     }
  712.     doOpen(actor) = {
  713.         if (wood_shavings.isIn(self))
  714.         setit(wood_shavings);
  715.     pass doOpen;
  716.     }
  717.     verDoSearch(actor) = {
  718.         if (self.isopen)
  719.         wood_shavings.verDoSearch(actor);
  720.     else
  721.         pass verDoSearch;
  722.     }
  723.     doSearch(actor)  = {
  724.         if (self.isopen)
  725.         wood_shavings.doSearch(actor);
  726.     else
  727.         pass doSearch;
  728.     }
  729.  
  730.     isopen = nil
  731.     location = attic
  732. ;
  733.  
  734. wood_shavings : searchHider
  735.     noun = 'shavings' 'shaving' 'wood'
  736.     adjective = 'wood'
  737.     sdesc = "wood shavings"
  738.     adesc = "some wood shavings"
  739.     ldesc = "It's just some ordinary wood shavings of the kind used as 
  740.         packing material. Obviously, this crate used to contain something 
  741.     fragile, perhaps something valuable. If anything still remains hidden
  742.     in the wood shavings, it must be pretty small. "
  743.     article = 'some'
  744.  
  745.     verifyRemove(actor) = {
  746.         "You take a few wood shavings from the crate, and then change
  747.     your mind: you don't really want them. ";
  748.     }
  749.  
  750.  
  751.     verDoLookin(actor) = {
  752.         self.verDoSearch(actor);
  753.     }
  754.     doLookin(actor) = {
  755.         self.doSearch(actor);
  756.     }    
  757.     verDoLookunder(actor) = {
  758.         self.verDoSearch(actor);
  759.     }
  760.     doLookunder(actor) = {
  761.         self.doSearch(actor);
  762.     }
  763.     
  764.     searchObj(actor, list) = {
  765.     local found, dest, i, tot;
  766.  
  767.         found := list;
  768.     list := nil;
  769.  
  770.     // set it to the found item(s)
  771.         if (length(found) = 1)
  772.         setit(found[1]);    // only one item - set 'it'
  773.     else
  774.         setit(found);       // multiple items - set 'them'
  775.  
  776.     // figure destination 
  777.     dest := self.location;
  778.     
  779.     // Note what we found, and move it to destination 
  780.     "You burrow through << self.thedesc >>, raising a lot of dust
  781.     in the process, when your hand touches something hard. It seems
  782.     you've found ";
  783.     
  784.     tot := length(found);
  785.     i := 1;    
  786.     while (i <= tot) {
  787.         found[i].adesc;
  788.         if (i+1 < tot) ", ";
  789.         else if (i = 1 and tot = 2) " and ";
  790.         else if (i+1 = tot and tot > 2) ", and ";
  791.         
  792.         found[i].moveInto(dest);
  793.         i := i + 1;
  794.     }
  795.  
  796.         ". ";
  797.  
  798.     if (list<>nil and length(list)=0) list := nil;
  799.     return(list);
  800.     }
  801.     
  802.     location = packing_crate
  803. ;
  804.  
  805.  
  806. /*
  807.  * The magic bottles
  808.  */
  809. class magic_bottle : breakable, container, treasure
  810.     noun = 'bottle'
  811.     
  812.     ioPutIn(actor, dobj) = {
  813.         if (dobj.bulk > 0) // Only small objects will fit inside
  814.         "That's too large to fit in << self.thedesc >>. ";
  815.     else 
  816.         pass ioPutIn;
  817.     }
  818.     
  819.     verDoEmpty(actor) = {
  820.      if (length(self.contents) = 0)
  821.         "\^<< self.thedesc >> is empty. ";
  822.     else
  823.         pass verDoEmpty;
  824.     }
  825. ;
  826.  
  827. receive_bottle : magic_bottle
  828.     adjective = 'blue'
  829.     sdesc = "blue bottle"
  830.     ldesc = {
  831.         "This bottle has an unusually wide neck - almost two centimetres 
  832.     in diameter - and is made of thick glass of a 
  833.     beautiful, deep blue colour. You estimate that it will
  834.     hold about half a litre of liquid. ";
  835.     if (itemcnt(contents) > 0) 
  836.         "It seems to contain << listcont(self) >>. ";
  837.     else 
  838.         "It is empty. ";
  839.     }
  840.  
  841.     location = cupboard
  842. ;
  843.  
  844. send_bottle : magic_bottle
  845.     adjective = 'green'
  846.     sdesc = "green bottle"
  847.     ldesc = {
  848.         "This bottle has an unusually wide neck - almost two centimetres 
  849.     in diameter - and is made of thick glass of a 
  850.     beautiful, sea-green colour. You estimate that it will
  851.     hold about half a litre of liquid. A neatly handwritten
  852.     label says 'FILL ME'. The bottle is empty. ";
  853.     }
  854.     location = sitting_room
  855.     used = nil
  856.     
  857.     ioPutIn(actor, dobj) = {
  858.         if (dobj.bulk > 0) // Only small objects will fit inside
  859.         "That's too large to fit in << self.thedesc >>. ";
  860.     else {
  861.         "As soon as it hits the bottom of the bottle, 
  862.         << dobj.thedesc >> vanishes with a popping sound. The
  863.         bottle is now empty. ";
  864.         if (receive_bottle.isVisible(actor.location))
  865.             "A split second later, %you% hear%s% a pinging noise
  866.         from << receive_bottle.thedesc >>. ";
  867.         dobj.moveInto(receive_bottle);
  868.         if (not used) {
  869.             incscore(5);
  870.         used := true;
  871.         }
  872.     }
  873.     }
  874. ;
  875.  
  876.  
  877. plate : readable, treasure
  878.     noun = 'plate' 'brass'
  879.     adjective = 'brass' 'old'
  880.     sdesc = "old brass plate"
  881.     adesc = "an old brass plate"
  882.     ldesc = "It's an old, rather thin plate of Indian brass, slightly dented 
  883.         and probably not worth very much. On the tarnished surface you can
  884.     just barely make out a rather clumsy depiction of a scorpion and
  885.     some stars - probably an astrological reference, since the
  886.     following text is engraved on the back side:\b
  887.     \tGOLD\tThe Sun, Ruler of the Daylit Sky\n
  888.     \tSILVER\tLuna, Mistress of the Night\n
  889.     \tMERCURY\tWing-footed Messenger of the Gods\n
  890.     \tCOPPER\tVenus, Carnal Love\n
  891.     \tIRON\tMars, Blood-red Bringer of War\n
  892.     \tTIN\t\tJupiter, Ruler of the Gods\n
  893.     \tLEAD\tSaturn, Lord of Time Itself "
  894.  
  895.     doRead(actor) = { self.ldesc; }
  896.     location = attic
  897. ;
  898.  
  899.